Hyunsoo Kim
  • Profile
  • Data Mining
  • R Basic
  • Data Visualization
  • Regression Analysis
  • Spatial Information Analysis
  • OpenData Analysis
  • Big Data Analysis Engineer

Visualization_with_seaborn_and_matplotlib

  • Profile
    • Profile
  • Study
    • Data Mining
    • R Basic
    • Data Visualization
    • Regression Analysis
    • Spatial Information Analysis
    • OpenData Analysis
    • Big Data Analysis Engineer

On this page

  • 처음으로 그려보는 그래프
  • 선의 스타일과 색상
  • 부분 그래프 (subplot)
  • 여러개의 그림 (figure)
  • 텍스트 그리기
  • 범례 (Legends)
  • 틱과 틱커 (Ticks and tickers)
  • 히스토그램
  • Visualization with seaborn
    • Loding dataset
  • 1. Creating basic plots
    • Line Chart
    • Bar Chart
    • Histogram
    • Box plots
    • Violin plot
    • Scatter plot
    • Hue semantic
    • Bubble plot
    • Category wise sub plot
  • 2. Advance categorical plots in seaborn
    • a. Categorical scatterplots
    • Strip plot
    • Swarm plot
    • b. Categorical distribution plots
    • Box Plots
    • Violin Plots
    • Point Plot
    • Bar plots
  • 3. Density Plots
    • Histogram and Density Plot
  • 4. Pair plots
  • Seaborn and Matplotlib
    • 1.1 Load data
    • 1.2 Figure and Axes
    • 1.3 plot with matplotlib
    • 1.4 Plot with seaborn
    • 1.5 matplotlib + seaborn & seaborn + matplotlib
    • 1.6 seaborn + seaborn + matplotlib

Visualization_with_seaborn_and_matplotlib

Python
Seaborn
Matplotlib
Author

Hyunsoo Kim

Published

May 7, 2022

seaborn과 matplotlib의 시각화

코드 출처 - 이제현님 블로그

  • https://jehyunlee.github.io/2020/09/30/Python-DS-34-seaborn_matplotlib/

  • 원문: by Aurélien Geron (Link)

  • Translated by Chansung PARK (Link)

  • Object Oriented API Addition by Jehyun LEE (Link)

처음으로 그려보는 그래프

데이터 몇 개로 plot 함수를 호출한 다음, show 함수를 호출해주면 간단히 그래프를 그려볼 수 있습니다!

plot 함수에 단일 배열의 데이터가 주어진다면, 수직 축의 좌표로서 이를 사용하게 되며, 각 데이터의 배열상 색인(인덱스)을 수평 좌표로서 사용합니다. 두 개의 배열을 넣어줄 수도 있습니다: 그러면, 하나는 x 축에 대한것이며, 다른 하나는 y 축에 대한것이 됩니다

import matplotlib
%matplotlib inline  
import matplotlib.pyplot as plt
plt.plot([1, 3, 4, 9, 1, 3])
plt.show() #객체지향이 아닌 기본적인 pyplot의 ploting 방법

같은 그림을 object oriented API를 이용해 그려보겠습니다.

object oriented API는 그래프의 각 부분을 객체로 지정하고 그리는 것으로, 다음과 같은 패턴을 가지고 있습니다.

# object oriented API (객체 지향 API)
# 1. 도화지(Figure: fig)를 깔고 그래프를 그릴 구역(Axes: ax)을 정의합니다.  
fig, ax = plt.subplots()

# 2. ax 위에 그래프를 그립니다.
ax.plot([1, 3, 4, 9, 1, 3])

# 3. 그래프를 화면에 출력합니다.
plt.show()

fig #이처럼 객체 지향은 fig라는 곳에 플롯을 저장해서 진행하는 스타일 

이번에는 수학적인 함수를 그려보겠습니다. NumPy의 linespace 함수를 사용하여 -2 ~ 2 범위에 속하는 500개의 부동소수로 구성된 x 배열을 생성합니다. 그 다음 x의 각 값의 거듭제곱된 값을 포함하는 y 배열을 생성합니다

그래프가 약간은 삭막해 보입니다. 타이틀과 x 및 y축에 대한 라벨, 그리고 모눈자를 추가적으로 그려보겠습니다.

# pyplot
import numpy as np
x = np.linspace(-2, 2, 500)
y = x**2
plt.plot(x, y)
plt.title("Square function")
plt.xlabel("x")
plt.ylabel("y = x**2")
plt.grid(True)
plt.show() 

  • object-oriented API는 축 이름과 같은 설정 명령어가 pyplot과 다소 다릅니다.
  • 대체로 축 이름(label), 범위(limits) 등을 지정하는 명령어는 set_대상(), 거꾸로 그래프에서 설정값을 가져오는 명령어는 get_대상()으로 통일되어 있습니다.
# object oriented API
fig, ax = plt.subplots()

ax.plot(x, y)
ax.set_title("Square function")
ax.set_xlabel("x")
ax.set_ylabel("y = x**2")
ax.grid(True) 

plt.show() #pyplot과 유사한 방식이지만 set이 추가되어 있는 모습이다

선의 스타일과 색상

기본적으로 matplotlib은 바로 다음에 위치한(연이은) 데이터 사이에 선을 그립니다.

세 번째 파라미터를 지정하면 선의 스타일과 색상을 바꿀 수 있습니다. 예를 들어서 “g–”는 “초록색 파선”을 의미합니다.

# object oriented API

fig, ax = plt.subplots()

ax.plot([0, 100, 100, 0, 0, 100, 50, 0, 100], [0, 0, 100, 100, 0, 100, 130, 100, 0])
ax.set_xlim(-10, 110)
ax.set_ylim(-10, 140)

# 그래프의 범위는 pyplot과 같이 ax.axis([-10, 110, -10, 140]) 으로 지정할 수 있습니다.
# 하지만 위와 같이 set_xlim, set_ylim을 사용해서 명시하는 것이 더 체계적으로 느껴집니다.

plt.show()

# object oriented API

fig, ax = plt.subplots()

ax.plot([0, 100, 100, 0, 0], [0, 0, 100, 100, 0], "r-") #선의 색생과 선의 종류를 지정
ax.plot([0, 100, 50, 0, 100], [0, 100, 130, 100, 0], "g--")
ax.set_xlim(-10, 110)
ax.set_ylim(-10, 140)

plt.show()

선 대신에 간단한 점을 그려보는 것도 가능합니다. 아래는 초록색 파선, 빨강 점선, 파랑 삼각형의 예를 보여줍니다.

# object oriented API

fig, ax = plt.subplots()

x = np.linspace(-1.4, 1.4, 30)

ax.plot(x, x, 'g--')
ax.plot(x, x**2, 'r:')
ax.plot(x, x**3, 'b^') #플롯을 하나씩 나누어서 그려주어 합쳐서 한줄에 쓰는 것보다 더 직관적이다 

plt.show()

# object oriented API

x = np.linspace(-1.4, 1.4, 30)

fig, ax = plt.subplots()

line1 = ax.plot(x, x, 'g--', linewidth=3, dash_capstyle='round') #linewidth로 굵기 dash_capstyle로 대쉬의 모형 선택
line2 = ax.plot(x, x**2, 'r:')
line3 = ax.plot(x, x**3, 'b^', alpha=0.2) #alpha로 투명도 조절

plt.show()

부분 그래프 (subplot)

matplotlib는 하나의 그림(figure)에 여러개의 부분 그래프를 포함할 수 있습니다. 이 부분 그래프는 격자 형식으로 관리됩니다. subplot 함수를 호출하여 부분 그래프를 생성할 수 있습니다. 이 때 격자의 행/열의 수 및 그래프를 그리고자 하는 부분 그래프의 색인을 파라미터로서 지정해줄 수 있습니다 (색인은 1부터 시작하며, 좌->우, 상단->하단의 방향입니다).

# object oriented API

x = np.linspace(-1.4, 1.4, 30)

fig, ax = plt.subplots(2, 2) # 행과 열의 개수를 지정

ax[0, 0].plot(x, x)    
ax[0, 1].plot(x, x**2)   
ax[1, 0].plot(x, x**3)   
ax[1, 1].plot(x, x**4) # ax[row, col]

plt.show()

# object oriented API

grid = plt.GridSpec(2, 2)  # 2행 2열 크기의 격자를 준비합니다.

ax1 = plt.subplot(grid[0, 0])  
ax2 = plt.subplot(grid[0, 1])  
ax3 = plt.subplot(grid[1, 0:]) # 2행의 전체열을 의미한다 

ax1.plot(x, x)
ax2.plot(x, x**2)
ax3.plot(x, x**3)

plt.show()

보다 복잡한 부분 그래프의 위치 선정이 필요하다면, subplot2grid를 대신 사용할 수 있습니다. 격자의 행과 열의 번호 및 격자에서 해당 부분 그래프를 그릴 위치를 지정해줄 수 있습니다 (좌측상단 = (0,0). 또한 몇 개의 행/열로 확장되어야 하는지도 추가적으로 지정할 수 있습니다.

# object oriented API - 객체지향 

gridsize = (3, 3)     # 3행 3열 크기의 격자를 준비합니다.
ax1 = plt.subplot2grid(gridsize, (0,0), rowspan=2, colspan=2) #행과 열 방향으로 각각 2씩 늘린다
ax2 = plt.subplot2grid(gridsize, (0,2))
ax3 = plt.subplot2grid(gridsize, (1,2), rowspan=2) #행 방향으로 2만큼 늘린다
ax4 = plt.subplot2grid(gridsize, (2,0), colspan=2) #열 방향으로 2만큼 늘린다 

ax1.plot(x, x**2)
ax2.plot(x, x**3)
ax3.plot(x, x**4)
ax4.plot(x, x**5)

plt.show() 

여러개의 그림 (figure)

여러개의 그림을 그리는것도 가능합니다. 각 그림은 하나 이상의 부분 그래프를 가질 수 있습니다. 기본적으로는 matplotlib이 자동으로 figure(1)을 생성합니다. 그림간 전환을 할 때, pyplot은 현재 활성화된 그림을 계속해서 추적합니다. 또한 활성화된 그림의 활성화된 부분 그래프가 현재 그래프가 그려질 부분 그래프가 됩니다.

# object oriented API

x = np.linspace(-1.4, 1.4, 30)

fig1, ax1 = plt.subplots(nrows=2, ncols=1) #2행 1열의 격자를 생성

ax1[0].plot(x, x**2)
ax1[0].set_title("Square and Cube")

ax1[1].plot(x, x**3)


fig2, ax2 = plt.subplots(nrows=1, ncols=2, figsize=(10, 5)) #격자의 크기를 지정
ax2[0].plot(x, x**4)
ax2[0].set_title("y = x**4")

ax2[1].plot(x, x**5)
ax2[1].set_title("y = x**5")

ax1[1].plot(x, -x**3, "r:")    # fig1의 두번째 그림에 추가되어 표현이 된다 
plt.show()

텍스트 그리기

text 함수를 호출하여 텍스트를 그래프의 원하는 위치에 추가할 수 있습니다. 출력을 원하는 텍스트와 수평 및 수직 좌표를 지정하고, 추가적으로 몇 가지 속성을 지정해 주기만 하면 됩니다. matplotlib의 모든 텍스트는 TeX 방정식 표현을 포함할 수 있습니다.

# object oriented API  
x = np.linspace(-1.5, 1.5, 30) #정해진 범위에 따라 숫자를 n개 만든다 
px = 0.8
py = px**2 #

fig, ax = plt.subplots() 

ax.plot(x, x**2, "b-")
ax.plot(px, py, "ro") #red색상과 o모양으로 설정 

ax.text(0, 1.5, "Square function\n$y = x^2$", fontsize=20, color='blue', horizontalalignment="center") #위치와 글자크기등을 설정해줌
ax.text(px - 0.08, py, "Beautiful point", ha="right", weight="heavy")
ax.text(px, py, "x = %0.2f\ny = %0.2f"%(px, py), rotation=50, color='gray') #rotation으로 기울기도 설정 

plt.show()

범례 (Legends)

범례를 추가하는 가장 간단한 방법은 모든 선에 라벨을 설정 해 주고, legend 함수를 호출하는 것입니다.

# object oriented API

x = np.linspace(-1.4, 1.4, 50)

fig, ax = plt.subplots()

ax.plot(x, x**2, "r--", label="Square function") #label을 이용해서 범례를 설정이 가능하다 
ax.plot(x, x**3, "g-", label="Cube function")
ax.legend(loc="best") 
ax.grid(True)
plt.show()

틱과 틱커 (Ticks and tickers)

각 축에는 “틱(ticks)”이라는 작은 표시가 있습니다. 정확히 말하자면, “틱”은 표시(예. (-1, 0, 1))의 위치”이며, 틱 선은 그 위치에 그려지는 작은 선입니다. 또한 “틱 라벨”은 틱 선 옆에 그려지는 라벨이며, “틱커”는 틱의 위치를 결정하는 객체 입니다. 기본적인 틱커는 ~5 에서 8 틱을 위치시키는데 꽤 잘 작동합니다. 즉, 틱 서로간에 적당한 거리를 표현합니다.

하지만, 가끔은 좀 더 이를 제어할 필요가 있습니다 (예. 위의 로짓 그래프에서는 너무 많은 틱 라벨이 있습니다). 다행히도 matplotlib은 틱을 완전히 제어하는 방법을 제공합니다. 심지어 보조 눈금(minor tick)을 활성화 할 수도 있습니다.

# object oriented API

x = np.linspace(-2, 2, 100)

fig, ax = plt.subplots(ncols=3, figsize=(15, 10)) #3열로 플롯을 그릴수 있도록

ax[0].plot(x, x**3)
ax[0].grid(True)
ax[0].set_title("Default ticks")

ax[1].plot(x, x**3)
ax[1].grid(True)
ax[1].set_xticks(np.arange(-2, 2, 1)) #xticks를 -2~1까지 1씩 증가하도록
ax[1].set_title("Manual ticks on the x-axis")

ax[2].plot(x, x**3)
ax[2].grid(True)
ax[2].minorticks_on()
ax[2].set_xticks([-2, 0, 1, 2], minor=False) #xticks를 지정
ax[2].set_yticks(np.arange(-5, 5, 1)) #yticks를 -5~4까지 1씩 증가하도록 
ax[2].set_yticklabels(["min", -4, -3, -2, -1, 0, 1, 2, 3, "max"]) #label를 지정해서 표현도 가능 
ax[2].set_title("Manual ticks and tick labels\n(plus minor ticks) on the y-axis")

plt.show()

산점도(Scatter plot)

단순히 각 점에 대한 x 및 y 좌표를 제공하면 산점도를 그릴 수 있습니다.

부수적으로 각 점의 크기를 정할 수도 있습니다.

마찬가지로 여러 속성을 설정할 수 있습니다. 가령 테두리 및 모양의 내부 색상, 그리고 투명도와 같은것의 설정이 가능합니다.

# object oriented API

from numpy.random import rand
x, y = rand(2, 100) #랜덤한 값들을 뽑아줌 

fig, ax = plt.subplots()
ax.scatter(x, y) #scatter함수로 스캐터 플롯으로 그릴수 있도록 해줌
plt.show()

# object oriented API

fig, ax = plt.subplots()

for color in ['red', 'green', 'blue']:
    n = 100
    x, y = rand(2, n)
    scale = 500.0 * rand(n) ** 5 #포인트들의 크기를 조절 
    ax.scatter(x, y, s=scale, c=color, alpha=0.3, edgecolors='blue') #지정해준 컬러와 투명도 테두리의 색상을 지정이 가능 

ax.grid(True)

plt.show()

# object oriented API

from numpy.random import randn

# Axis를 인자로 전달하여 함수 연산과 시각화를 수행합니다.
def plot_line(axis, slope, intercept, **kargs):
    xmin, xmax = axis.get_xlim()
    axis.plot([xmin, xmax], [xmin*slope+intercept, xmax*slope+intercept], **kargs)

x = randn(1000)
y = 0.5*x + 5 + randn(1000)*2

fig, ax = plt.subplots()

ax.set_xlim(-2.5, 2.5) #x축의 범위지정
ax.set_ylim(-5, 15) #y축의 범위지정
ax.scatter(x, y, alpha=0.2) #alpha=0.2로 투명도 설정 
ax.plot(1, 0, "ro") #포인트를 red색상 o모양으로 표시
ax.vlines(1, -5, 0, color="red") #세로 라인
ax.hlines(0, -2.5, 1, color="red") #가로 라인을 표시 
plot_line(axis=ax, slope=0.5, intercept=5, color="magenta")  #기울기 0.5이고 beta_0가 5인 직선
ax.grid(True)
plt.show()

히스토그램

# object oriented API

data = [1, 1.1, 1.8, 2, 2.1, 3.2, 3, 3, 3, 3]

fig, ax = plt.subplots(2, 1)
ax[0].hist(data, bins = 5, rwidth=0.8) #bin - x축에서 막대그래프의 폭을 설정 

ax[1].hist(data, bins = [1, 1.5, 2, 2.5, 3], rwidth=0.95) #rwidth로 row의 넓이를 설정 
ax[1].set_xlabel("Value")
ax[1].set_ylabel("Frequency")

plt.show()

# object oriented API

data1 = np.random.randn(400)
data2 = np.random.randn(500) + 3 # x축에서 +3만큼 원점을 이동해서 플롯팅
data3 = np.random.randn(450) + 6
data4a = np.random.randn(200) + 9
data4b = np.random.randn(100) + 10

fig, ax = plt.subplots()
ax.hist(data1, bins=5, color='g', alpha=0.75, label='bar hist') # 기본적인 histtype='bar'
ax.hist(data2, color='b', alpha=0.65, histtype='stepfilled', label='stepfilled hist')
ax.hist(data3, color='r', histtype='step', label='step hist')
ax.hist((data4a, data4b), color=('r','m'), alpha=0.55, histtype='barstacked', label=('barstacked a', 'barstacked b'))

ax.set_xlabel("Value") # x축의 이름 지정
ax.set_ylabel("Frequency")
ax.legend()
ax.grid(True) # 한번에 여러개의 플롯을 그리는 경우 
plt.show()

Visualization with seaborn

seaborn은 python의 시각화 라이브러리인 matplolib를 기반으로 제작된 라이브러리입니다.

import seaborn as sns
sns.set()
sns.set(style="darkgrid")

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
%matplotlib inline

import warnings
warnings.filterwarnings("ignore")
plt.rcParams['figure.figsize']=(5,5) #figure의 사이즈를 설정이 가능하다 

Loding dataset

# 사용할 데이터 불러오기 
data_BM = pd.read_csv('bigmart_data.csv')
data_BM = data_BM.dropna(how="any") #NA값 제거
data_BM["Visibility_Scaled"] = data_BM["Item_Visibility"] * 100 #Visibility_Scaled 컬럼의 값들에 100 곱해줌
data_BM.head()
Item_Identifier Item_Weight Item_Fat_Content Item_Visibility Item_Type Item_MRP Outlet_Identifier Outlet_Establishment_Year Outlet_Size Outlet_Location_Type Outlet_Type Item_Outlet_Sales Visibility_Scaled
0 FDA15 9.300 Low Fat 0.016047 Dairy 249.8092 OUT049 1999 Medium Tier 1 Supermarket Type1 3735.1380 1.604730
1 DRC01 5.920 Regular 0.019278 Soft Drinks 48.2692 OUT018 2009 Medium Tier 3 Supermarket Type2 443.4228 1.927822
2 FDN15 17.500 Low Fat 0.016760 Meat 141.6180 OUT049 1999 Medium Tier 1 Supermarket Type1 2097.2700 1.676007
4 NCD19 8.930 Low Fat 0.000000 Household 53.8614 OUT013 1987 High Tier 3 Supermarket Type1 994.7052 0.000000
5 FDP36 10.395 Regular 0.000000 Baking Goods 51.4008 OUT018 2009 Medium Tier 3 Supermarket Type2 556.6088 0.000000
data_BM.describe() #이상치가 있는지 확인
Item_Weight Item_Visibility Item_MRP Outlet_Establishment_Year Item_Outlet_Sales Visibility_Scaled
count 4650.000000 4650.000000 4650.000000 4650.000000 4650.000000 4650.000000
mean 12.898675 0.060700 141.716328 1999.190538 2272.037489 6.070048
std 4.670973 0.044607 62.420534 7.388800 1497.964740 4.460652
min 4.555000 0.000000 31.490000 1987.000000 69.243200 0.000000
25% 8.770000 0.025968 94.409400 1997.000000 1125.202000 2.596789
50% 12.650000 0.049655 142.979900 1999.000000 1939.808300 4.965549
75% 17.000000 0.088736 186.614150 2004.000000 3111.616300 8.873565
max 21.350000 0.188323 266.888400 2009.000000 10256.649000 18.832266

1. Creating basic plots

matplotlib에서 여러 줄이 필요한 한 줄로 seaborn에서 몇 가지 기본 플롯을 만드는 방법을 살펴보겠습니다.

Line Chart

  • 일부 데이터 세트의 경우 한 변수의 변화를 시간의 함수로 이해하거나 이와 유사한 연속 변수를 이해하고자 할 수 있습니다.

  • seaborn에서 이는 lineplot() 함수로 직접 또는 kind="line":을 설정하여 relplot()으로 수행할 수 있습니다.

sns.lineplot(x="Item_Weight", y="Item_MRP",data=data_BM[:50]); #처음부터 50번째 까지의 데이터만 사용한다

Bar Chart

  • Seaborn에서는 barplot 기능을 사용하여 간단하게 막대 차트를 생성할 수 있습니다.
  • matplotlib에서 동일한 결과를 얻으려면 데이터 범주를 현명하게 그룹화하기 위해 추가 코드를 작성해야 했습니다.
  • 그리고 나서 플롯이 올바르게 나오도록 훨씬 더 많은 코드를 작성해야 했습니다.
sns.barplot(x="Item_Type", y="Item_MRP", data=data_BM[:5])
<AxesSubplot:xlabel='Item_Type', ylabel='Item_MRP'>

Histogram

  • distplot()을 사용하여 seaborn에서 히스토그램을 만들 수 있습니다. 사용할 수 있는 여러 옵션이 있으며 노트북에서 더 자세히 살펴보겠습니다.
sns.distplot(data_BM['Item_MRP'])
<AxesSubplot:xlabel='Item_MRP', ylabel='Density'>

Box plots

  • Seaborn에서 boxplot을 생성하기 위해 boxplot()을 사용할 수 있습니다.
sns.boxplot(data_BM['Item_Outlet_Sales'], orient='vertical') 
<AxesSubplot:xlabel='Item_Outlet_Sales'>

Violin plot

  • 바이올린 플롯은 상자 및 수염 플롯과 유사한 역할을 합니다.
  • 이는 하나(또는 그 이상) 범주형 변수의 여러 수준에 걸친 정량적 데이터의 분포를 보여줌으로써 해당 분포를 비교할 수 있습니다.
  • 모든 플롯 구성 요소가 실제 데이터 포인트에 해당하는 상자 플롯과 달리 바이올린 플롯은 기본 분포의 커널 밀도 추정을 특징으로 합니다.
  • seaborn에서 violinplot()을 사용하여 바이올린 플롯을 만들 수 있습니다.
sns.violinplot(data_BM['Item_Outlet_Sales'], orient='vertical', color='skyblue')
<AxesSubplot:xlabel='Item_Outlet_Sales'>

Scatter plot

  • 각 포인트는 데이터 세트의 관찰을 나타내는 포인트 클라우드를 사용하여 두 변수의 분포를 나타냅니다.
  • 이 묘사를 통해 눈은 그들 사이에 의미 있는 관계가 있는지 여부에 대한 상당한 양의 정보를 추론할 수 있습니다.
  • relplot()을 kind=scatter 옵션과 함께 사용하여 seaborn에서 산점도를 그릴 수 있습니다.
sns.relplot(x="Item_MRP", y="Item_Outlet_Sales", data=data_BM[:200], kind="scatter"); 
#sns.relplot(x="Item_MRP", y="Item_Outlet_Sales", data=data_BM[:200], kind="line"); #kind의 설정으로 표현 설정을 바꿈

Hue semantic

세 번째 변수에 따라 점을 색칠하여 플롯에 다른 차원을 추가할 수도 있습니다. Seaborn에서는 이것을 “hue semantic” 사용이라고 합니다.

sns.relplot(x="Item_MRP", y="Item_Outlet_Sales", hue="Item_Type",data=data_BM[:200]); #hue로 item_type에 대한 플롯을 그려줌 

sns.lineplot(x="Item_Weight", y="Item_MRP",hue='Outlet_Size',data=data_BM[:150]);

Bubble plot

  • hue semantic 활용하여 Item_Visibility별로 거품을 색칠함과 동시에 개별 거품의 크기로 사용합니다.
# Bubble plot
sns.relplot(x="Item_MRP", y="Item_Outlet_Sales", data=data_BM[:200], kind="scatter", size="Visibility_Scaled", hue="Visibility_Scaled");

Category wise sub plot

  • Seaborn에서 카테고리를 기반으로 플롯을 만들 수도 있습니다.
  • 각 Outlet_Size에 대한 산점도를 만들었습니다.
sns.relplot(x="Item_Weight", y="Item_Visibility",
            hue='Outlet_Size',style='Outlet_Size',
            col='Outlet_Size',data=data_BM[:100]); 

2. Advance categorical plots in seaborn

범주형 변수의 경우 seaborn에 세 가지 다른 패밀리가 있습니다.

catplot()에서 데이터의 기본 표현은 산점도를 사용합니다.

a. Categorical scatterplots

Strip plot

  • 하나의 변수가 범주형인 산점도를 그립니다.
  • catplot()에서 kind=strip을 전달하여 생성할 수 있습니다.
sns.catplot(x="Outlet_Size", y="Item_Outlet_Sales", kind='strip',data=data_BM[:250]);

Swarm plot

  • 이 함수는 stripplot()과 유사하지만 점이 겹치지 않도록 조정됩니다(범주형 축을 따라만).
  • 이렇게 하면 값 분포를 더 잘 표현할 수 있지만 많은 수의 관측치에 대해서는 잘 확장되지 않습니다. 이러한 스타일의 플롯은 때때로 “beeswarm”이라고 불립니다.
  • catplot()에서 kind=swarm을 전달하여 이를 생성할 수 있습니다.
sns.catplot(x="Outlet_Size", y="Item_Outlet_Sales", kind='swarm',data=data_BM[:250]);

b. Categorical distribution plots

Box Plots

  • 상자 그림은 극단값과 함께 분포의 3사분위수 값을 보여줍니다.
  • “whiskers”은 하위 및 상위 사분위수의 1.5 IQR 내에 있는 점으로 확장되고 이 범위를 벗어나는 관찰은 독립적으로 표시됩니다.
  • 즉, 상자 그림의 각 값은 데이터의 실제 관측값에 해당합니다.
sns.catplot(x="Outlet_Size", y="Item_Outlet_Sales",kind="box",data=data_BM);

Violin Plots

sns.catplot(x="Outlet_Size", y="Item_Outlet_Sales",kind="violin",data=data_BM);

Point Plot

sns.catplot(x="Outlet_Size", y="Item_Outlet_Sales",kind="point",data=data_BM); #y축은 연속형 플랏 x축은 범주형 

Bar plots

sns.catplot(x="Outlet_Size", y="Item_Outlet_Sales",kind="bar",data=data_BM);

3. Density Plots

히스토그램 대신 Seaborn이 sn.kdeplot으로 수행하는 커널 밀도 추정을 사용하여 분포의 부드러운 추정치를 얻을 수 있습니다.:

# distribution of Item Visibility
plt.figure(figsize=(5,5))
sns.kdeplot(data_BM['Item_Visibility'], shade=True);

Histogram and Density Plot

distplot을 사용하여 히스토그램과 KDE를 결합할 수 있습니다.:

plt.figure(figsize=(10,10))
sns.distplot(data_BM['Item_Outlet_Sales']);

4. Pair plots

  • 조인트 플롯을 더 큰 차원의 데이터세트로 일반화하면 쌍 플롯으로 끝납니다. 이것은 모든 값 쌍을 서로에 대해 플롯하려는 경우 다차원 데이터 간의 상관 관계를 탐색하는 데 매우 유용합니다.

  • 세 가지 붓꽃 종의 꽃잎과 꽃받침 측정값을 나열하는 잘 알려진 Iris 데이터 세트를 사용하여 이것을 시연할 것입니다.

iris = sns.load_dataset("iris")
sns.pairplot(iris, hue='species', height=2.5); #둘다 연속형이면 scatter플랏으로 보여줌 

Seaborn and Matplotlib

1.1 Load data

  • 예제로 사용할 펭귄 데이터를 불러옵니다.
  • seaborn에 내장되어 있습니다.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

penguins = sns.load_dataset("penguins")
penguins.head()
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex
0 Adelie Torgersen 39.1 18.7 181.0 3750.0 Male
1 Adelie Torgersen 39.5 17.4 186.0 3800.0 Female
2 Adelie Torgersen 40.3 18.0 195.0 3250.0 Female
3 Adelie Torgersen NaN NaN NaN NaN NaN
4 Adelie Torgersen 36.7 19.3 193.0 3450.0 Female

1.2 Figure and Axes

  • matplotlib으로 도화지figure를 깔고 축공간axes를 만듭니다.
  • 1 x 2 축공간을 구성합니다.
fig, axes = plt.subplots(ncols=2, figsize=(8,4))

fig.tight_layout()

1.3 plot with matplotlib

  • matplotlib 기능을 이용해서 산점도를 그립니다.
    • x축은 부리 길이 bill length
    • y축은 부리 위 아래 두께 bill depth
    • 색상은 종species로 합니다.
    • Adelie, Chinstrap, Gentoo이 있습니다.
  • 두 축공간 중 왼쪽에만 그립니다.
fig, axes = plt.subplots(ncols=2,figsize=(8,4))

species_u = penguins["species"].unique()

for i, s in enumerate(species_u):
    axes[0].scatter(penguins["bill_length_mm"].loc[penguins["species"]==s],
                    penguins["bill_depth_mm"].loc[penguins["species"]==s],
                    c=f"C{i}", label=s, alpha=0.3)
    
axes[0].legend(species_u, title="species")
axes[0].set_xlabel("Bill Length (mm)")
axes[0].set_ylabel("Bill Depth (mm)")

# plt.show()
fig.tight_layout()

1.4 Plot with seaborn

  • 단 세 줄로 거의 동일한 그림이 나왔습니다.
    • scatter plot의 점 크기만 살짝 작습니다.
    • label의 투명도만 살짝 다릅니다.
  • seaborn 명령 scatterplot()을 그대로 사용했습니다.
  • x축과 y축 label도 바꾸었습니다.
    • ax=axes[1] 인자에서 볼 수 있듯, 존재하는 axes에 그림만 얹었습니다.
    • matplotlib 틀 + seaborn 그림 이므로, matplotlib 명령이 모두 통합니다.
fig, axes = plt.subplots(ncols=2,figsize=(8,4))

species_u = penguins["species"].unique()

# plot 0 : matplotlib

for i, s in enumerate(species_u):
    axes[0].scatter(penguins["bill_length_mm"].loc[penguins["species"]==s],
                    penguins["bill_depth_mm"].loc[penguins["species"]==s],
                    c=f"C{i}", label=s, alpha=0.3)
    
axes[0].legend(species_u, title="species")
axes[0].set_xlabel("Bill Length (mm)")
axes[0].set_ylabel("Bill Depth (mm)")


# plot 1 : seaborn
sns.scatterplot(x="bill_length_mm", y="bill_depth_mm", hue="species", data=penguins, alpha=0.3, ax=axes[1])
axes[1].set_xlabel("Bill Length (mm)")
axes[1].set_ylabel("Bill Depth (mm)")

fig.tight_layout()

1.5 matplotlib + seaborn & seaborn + matplotlib

  • matplotlib과 seaborn이 자유롭게 섞일 수 있습니다.
    • matplotlib 산점도 위에 seaborn 추세선을 얹을 수 있고,
    • seaborn 산점도 위에 matplotlib 중심점을 얹을 수 있습니다.
fig, axes = plt.subplots(ncols=2, figsize=(8, 4))

species_u = penguins["species"].unique()

# plot 0 : matplotlib + seaborn
for i, s in enumerate(species_u):
    # matplotlib 산점도
    axes[0].scatter(penguins["bill_length_mm"].loc[penguins["species"]==s],
                   penguins["bill_depth_mm"].loc[penguins["species"]==s],
                   c=f"C{i}", label=s, alpha=0.3
                  )
                  
    # seaborn 추세선
    sns.regplot(x="bill_length_mm", y="bill_depth_mm", data=penguins.loc[penguins["species"]==s], 
                scatter=False, ax=axes[0])
    
axes[0].legend(species_u, title="species")
axes[0].set_xlabel("Bill Length (mm)")
axes[0].set_ylabel("Bill Depth (mm)")

# plot 1 : seaborn + matplotlib
# seaborn 산점도
sns.scatterplot(x="bill_length_mm", y="bill_depth_mm", hue="species", data=penguins, alpha=0.3, ax=axes[1])
axes[1].set_xlabel("Bill Length (mm)")
axes[1].set_ylabel("Bill Depth (mm)")

for i, s in enumerate(species_u):
    # matplotlib 중심점
    axes[1].scatter(penguins["bill_length_mm"].loc[penguins["species"]==s].mean(),
                   penguins["bill_depth_mm"].loc[penguins["species"]==s].mean(),
                   c=f"C{i}", alpha=1, marker="x", s=100
                  )

fig.tight_layout()

1.6 seaborn + seaborn + matplotlib

  • seaborn scatterplot + seaborn kdeplot + matplotlib text입니다
fig, ax = plt.subplots(figsize=(6,5))

# plot 0: scatter plot
sns.scatterplot(x="bill_length_mm", y="bill_depth_mm", color="k", data=penguins, alpha=0.3, ax=ax, legend=False)

# plot 1: kde plot
sns.kdeplot(x="bill_length_mm", y="bill_depth_mm", hue="species", data=penguins, alpha=0.5, ax=ax, legend=False)

# text:
species_u = penguins["species"].unique()
for i, s in enumerate(species_u):
    ax.text(penguins["bill_length_mm"].loc[penguins["species"]==s].mean(),
            penguins["bill_depth_mm"].loc[penguins["species"]==s].mean(),
            s = s, fontdict={"fontsize":14, "fontweight":"bold","color":"k"}
            )

ax.set_xlabel("Bill Length (mm)")
ax.set_ylabel("Bill Depth (mm)")

fig.tight_layout()